#ifndef EXPRESSION_H
#define EXPRESSION_H

#include <sstream>
using namespace std;

class Expression
{
	class BinaryExpression;
	class Number;

	virtual void selfFromString(const string s);
	virtual void append(Expression* e)
	{
		if(value)
			value->append(e);
		else
			value = e;
	}
	virtual int getImportance(void) const
	{
		if(value) return value->getImportance();
		return 0;
	}

	Expression* value;
public:
	Expression(const string s = "") : value(NULL) 
	{
		selfFromString(s);
	}
	virtual string toString() const
	{
		if(value) return value->toString();
		else return "[Empty Expression]";
	}
	virtual ~Expression(void)
	{
		if(value) delete value;
	}
};

class Expression::BinaryExpression : public Expression
{
	virtual void append(Expression* e)
	{
		if(!left) 
			left = e;
		else if(!right) 
			right = e;
		else if(right) 
		{
			int a = right->getImportance();
			int b = e->getImportance();
			if(right->getImportance() > e->getImportance())
			{
				e->append(right);
				right = e;
			}
			else
				right->append(e);
		}
	}
	virtual int getImportance(void) const
	{
		return (0 - (string("^^/*-+").find(op)/2+1));
	}

	const char op;
	Expression* left;
	Expression* right;
public:
	BinaryExpression(char operation, Expression* l = NULL, Expression* r = NULL) : op(operation), left(l), right(r)
	{
	}
	virtual string toString(void) const;
	virtual ~BinaryExpression(void)
	{
		if(left) delete left;
		if(right) delete right;
	}
};

class Expression::Number : public Expression
{
	virtual void append(Expression* e)
	{
		cout << "Trying to append to a number?" << endl;
		system("pause");
		exit(1);
	}
	virtual int getImportance(void) const
	{
		return 1;
	}
	float value;
public:
	Number(float f) : value(f) {;;;}
	virtual string toString() const
	{
		stringstream s;
		s << value;
		return s.str();
	}
};

#endif